package at.ac.thornwishstalon.ocrapp.pic;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Log;

public class OCRAPPcropTool {
	public static final String TAG="cropTool";
	public static final int INSIDE=0;
	public static final int TOP=1;
	public static final int LEFT=2;
	public static final int RIGHT=3;
	public static final int BOTTOM=4;
	public static final int NOT=5;

	private RectF boundary=new RectF();
	private RectF top =new RectF();
	private RectF left=new RectF();
	private RectF right =new RectF();
	private RectF bottom =new RectF();
	private RectF innerBoundary=new RectF();
	private RectF outerBoundary=new RectF();
	private PaintBucket paint;
	private float recWidth=25f;
	private float width=240;
	private float height=160;

	private int mode=NOT;

	private Matrix mat= new Matrix();
	private RectF check= new RectF();

	public OCRAPPcropTool(float x, float y){
		paint= PaintBucket.getInstance();

		boundary.set(x-width/2, y-height/2, x+width/2, y+height/2);
		top.set(boundary.centerX()-recWidth, boundary.top-recWidth, boundary.centerX()+recWidth, boundary.top+recWidth);
		bottom.set(boundary.centerX()-recWidth, boundary.bottom-recWidth, boundary.centerX()+recWidth, boundary.bottom+recWidth);

		left.set(boundary.left-recWidth,boundary.centerY()-recWidth, boundary.left+recWidth, boundary.centerY()+recWidth);
		right.set(boundary.right-recWidth,boundary.centerY()-recWidth, boundary.right+recWidth, boundary.centerY()+recWidth);

		innerBoundary.set(left.right, top.bottom, right.left, bottom.top);
		outerBoundary.set(left.left, top.top, right.right, bottom.bottom);
		Log.d("recTOOL", "x-"+boundary.centerX()+" y-"+boundary.centerY());
	}


	void onDrawCanvas(Canvas c){
		switch(mode){
		case INSIDE:
			c.drawRect(boundary, paint.get(Color.RED,Paint.Style.FILL,70));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.STROKE,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			//c.drawLine(startX, startY, stopX, stopY, paint)

			break;
		case TOP:
			c.drawRect(boundary, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.STROKE,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.RED,Paint.Style.FILL,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			break;
		case BOTTOM:
			c.drawRect(boundary, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.STROKE,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.RED,Paint.Style.FILL,70));
			break;
		case RIGHT:
			c.drawRect(boundary, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.STROKE,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.RED,Paint.Style.FILL,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			break;
		case LEFT:
			c.drawRect(boundary, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.FILL,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.RED,Paint.Style.FILL,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			break;
		case NOT:
			c.drawRect(boundary, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			//c.drawRect(innerBoundary, paint.get(Color.WHITE));
			//c.drawRect(outerBoundary, paint.get(Color.WHITE));
			c.drawCircle(boundary.centerX(), boundary.centerY(), 5, paint.get(Color.BLUE,Paint.Style.STROKE,70));
			c.drawCircle(top.centerX(), top.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(left.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(right.centerX(), left.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));
			c.drawCircle(bottom.centerX(), bottom.centerY(), recWidth, paint.get(Color.WHITE,Paint.Style.STROKE,70));

		}


	}

	public int check(float x, float y){
		int mode;
		if(innerBoundary.contains(x, y)){
			return INSIDE;
		} 
		else if(outerBoundary.contains(x, y)){
			if(top.contains(x, y))
				mode= TOP;
			else if(left.contains(x, y))
				mode= LEFT;
			else if(right.contains(x, y))
				mode= RIGHT;
			else if(bottom.contains(x, y))
				mode= BOTTOM;
			else mode= NOT;
		} else mode= NOT;

		Log.d("tool", "mode: "+mode);
		return mode;
	}

	public void setMode(int mod){
		mode=mod;
	}

	private void update(){
		Log.i(TAG, "update..."+boundary.toString());
		//boundary.set(x-width/2, y-height/2, x+width/2, y+height/2); // update 

		top.set(boundary.centerX()-recWidth, boundary.top-recWidth, boundary.centerX()+recWidth, boundary.top+recWidth);
		bottom.set(boundary.centerX()-recWidth, boundary.bottom-recWidth, boundary.centerX()+recWidth, boundary.bottom+recWidth);

		left.set(boundary.left-recWidth,boundary.centerY()-recWidth, boundary.left+recWidth, boundary.centerY()+recWidth);
		right.set(boundary.right-recWidth,boundary.centerY()-recWidth, boundary.right+recWidth, boundary.centerY()+recWidth);

		innerBoundary.set(left.right, top.bottom, right.left, bottom.top);
		outerBoundary.set(left.left, top.top, right.right, bottom.bottom);	
	}

	public void setTop(float top){
		Log.d("tool", "setTOP "+top+" -> "+boundary.top);
		boundary.top=top;
		Log.d("tool", ":"+boundary.top);
		update();
	}

	public void setBottom(float bottom){
		Log.d(TAG,bottom+"");
		boundary.bottom=bottom; // update
		update();
	}
	public void setLeft(float left){
		Log.d(TAG,left+"");
		boundary.left=left;
		update();
	}
	public void setRight(float right){
		Log.d(TAG,right+"");
		boundary.right=right;
		update();
	}

	public void setInside(float dx, float dy){

		mat.setTranslate(dx, dy);

		mat.mapRect(boundary);
		update();

	}

	public boolean setInside(RectF imageBoundary, float dx, float dy){
		check.set(boundary);
		mat.setTranslate(dx, dy);
		mat.mapRect(check);

		if(imageBoundary.contains(check)){
			mat.mapRect(boundary);
			update();
			return true;
		}
		else return false;
	}

	public RectF getBoundary(){
		return boundary;
	}





	public boolean setTop(float deltaY, float imageBoundary) {
		if((boundary.top + deltaY > imageBoundary) && (boundary.top + deltaY < boundary.bottom-30)){
			boundary.top=boundary.top+ deltaY; 
			update();
			return true;
		}
		else return false;		
	}

	public boolean setBottom(float deltaY, float imageBoundary) {
		if(boundary.bottom + deltaY < imageBoundary && boundary.bottom + deltaY > boundary.top+30){
			boundary.bottom = boundary.bottom+ deltaY;
			update();
			return true;
		}
		else return false;		
	}

	public boolean setRight(float deltaX, float imageBoundary) {
		if(boundary.right +deltaX < imageBoundary && boundary.right + deltaX > boundary.left+30){
			boundary.right= boundary.right+ deltaX; 
			update();
			return true;
		}
		else return false;		
	}
	public boolean setLeft(float deltaX, float imageBoundary) {
		if(boundary.left + deltaX > imageBoundary && boundary.left + deltaX < boundary.right-30){
			boundary.left= boundary.left+deltaX; 
			update();
			return true;
		}
		else return false;		
	}

	public void setStart(RectF start){
		boundary.set(start);
		update();
	}





}
